//////////////////////////////////////////////////////////////////////////
// $Id: MMutex.cpp,v 1.1 2009/04/03 12:46:10 sunjun Exp $
//////////////////////////////////////////////////////////////////////////

#include "Local.h"

//////////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////////

NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////////

	INLINE MMutex::MMutex() 
	{
		GUARD(MMutex::MMutex);

		CRITICAL_SECTION * cs = MNEW(CRITICAL_SECTION);
		mData = static_cast<VOID *>(cs);
		::InitializeCriticalSection( cs );

		UNGUARD;
	}

	INLINE MMutex::~MMutex() 
	{
		GUARD(MMutex::~MMutex);

		CRITICAL_SECTION * cs = static_cast<CRITICAL_SECTION*>(mData);
		::DeleteCriticalSection( cs );
		MDELETE( cs );

		UNGUARD;
	}

	/*
	====================
	lock
	====================
	*/
	INLINE I32 MMutex::lock() const
	{
		GUARD(MMutex::lock);

		// block until we can take this lock.
		:: EnterCriticalSection( static_cast<CRITICAL_SECTION*>(mData) );
		return 0;

		UNGUARD;
	}

	/*
	====================
	unlock
	====================
	*/
	INLINE I32 MMutex::unlock() const
	{
		GUARD(MMutex::unlock);

		// release this lock. CRITICAL_SECTION is nested, thus
		// unlock() calls must be paired with lock() calls.
		::LeaveCriticalSection( static_cast<CRITICAL_SECTION*>(mData) );
		return 0;

		UNGUARD;
	}
	
	//////////////////////////////////////////////////////////////////////////

	INLINE MLock::MLock( const MMutex* m ) : mMutex(m) 
	{
		GUARD(MLock::MLock);

		if( mMutex ) mMutex->lock();

		UNGUARD;
	}

    INLINE MLock::~MLock()
	{
		GUARD(MLock::~MLock);

		if( mMutex ) mMutex->unlock();

		UNGUARD;
	}

//////////////////////////////////////////////////////////////////////////

NAMESPACE_END

//////////////////////////////////////////////////////////////////////////
